package com.cencat.merchant.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.*;
import lombok.Data;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;

/**
 * 派单创建DTO
 * 
 * @author cencat
 * @since 2024
 */
@Data
@Schema(description = "派单创建请求对象")
public class DispatchCreateDTO {
    
    /**
     * 租户ID
     */
    @NotNull(message = "租户ID不能为空")
    @Schema(description = "租户ID", example = "1")
    private Long tenantId;
    
    /**
     * 订单ID
     */
    @NotNull(message = "订单ID不能为空")
    @Schema(description = "订单ID", example = "1001")
    private Long orderId;
    
    /**
     * 商家ID
     */
    @NotNull(message = "商家ID不能为空")
    @Schema(description = "商家ID", example = "2001")
    private Long merchantId;
    
    /**
     * 司机ID(手动派单时必填)
     */
    @Schema(description = "司机ID(手动派单时必填)", example = "3001")
    private Long driverId;
    
    /**
     * 派单类型(0-自动,1-手动,2-指定)
     */
    @NotNull(message = "派单类型不能为空")
    @Min(value = 0, message = "派单类型值无效")
    @Max(value = 2, message = "派单类型值无效")
    @Schema(description = "派单类型(0-自动,1-手动,2-指定)", example = "0")
    private Integer assignType;
    
    /**
     * 优先级(1-最高,2-高,3-中,4-低,5-最低)
     */
    @Min(value = 1, message = "优先级值无效")
    @Max(value = 5, message = "优先级值无效")
    @Schema(description = "优先级(1-最高,2-高,3-中,4-低,5-最低)", example = "3")
    private Integer priority = 3;
    
    /**
     * 订单位置信息(经纬度)
     */
    @NotNull(message = "订单位置信息不能为空")
    @Schema(description = "订单位置信息(包含latitude和longitude)", 
            example = "{\"latitude\": 39.9042, \"longitude\": 116.4074}")
    private Map<String, Double> orderLocation;
    
    /**
     * 最大派单距离(公里)
     */
    @DecimalMin(value = "0.1", message = "最大派单距离不能小于0.1公里")
    @DecimalMax(value = "50.0", message = "最大派单距离不能超过50公里")
    @Schema(description = "最大派单距离(公里)", example = "10.0")
    private BigDecimal maxDistance = BigDecimal.valueOf(10.0);
    
    /**
     * 最小司机评分
     */
    @DecimalMin(value = "1.0", message = "最小司机评分不能低于1分")
    @DecimalMax(value = "5.0", message = "最小司机评分不能高于5分")
    @Schema(description = "最小司机评分", example = "4.0")
    private BigDecimal minDriverRating = BigDecimal.valueOf(3.0);
    
    /**
     * 派单算法类型(1-距离优先,2-评分优先,3-负载均衡,4-专属绑定,5-智能派单)
     */
    @Min(value = 1, message = "派单算法类型值无效")
    @Max(value = 5, message = "派单算法类型值无效")
    @Schema(description = "派单算法类型(1-距离优先,2-评分优先,3-负载均衡,4-专属绑定,5-智能派单)", example = "5")
    private Integer algorithmType = 5;
    
    /**
     * 算法权重配置(智能派单时使用)
     */
    @Schema(description = "算法权重配置(包含distance、rating、load等权重)", 
            example = "{\"distance\": 0.4, \"rating\": 0.3, \"load\": 0.3}")
    private Map<String, Double> algorithmWeights;
    
    /**
     * 预计送达时间
     */
    @Schema(description = "预计送达时间", example = "2024-01-01T12:30:00")
    private LocalDateTime estimatedArrivalTime;
    
    /**
     * 派单备注
     */
    @Size(max = 500, message = "派单备注长度不能超过500个字符")
    @Schema(description = "派单备注", example = "紧急订单，请优先处理")
    private String dispatchRemark;
    
    /**
     * 操作人ID
     */
    @Schema(description = "操作人ID", example = "1001")
    private Long operatorId;
    
    /**
     * 操作人姓名
     */
    @Size(max = 50, message = "操作人姓名长度不能超过50个字符")
    @Schema(description = "操作人姓名", example = "张三")
    private String operatorName;
    
    /**
     * 是否强制派单(忽略司机状态限制)
     */
    @Schema(description = "是否强制派单", example = "false")
    private Boolean forceDispatch = false;
    
    /**
     * 排除的司机ID列表
     */
    @Schema(description = "排除的司机ID列表", example = "[1001, 1002]")
    private java.util.List<Long> excludeDriverIds;
    
    /**
     * 指定的司机ID列表(仅从这些司机中选择)
     */
    @Schema(description = "指定的司机ID列表", example = "[2001, 2002, 2003]")
    private java.util.List<Long> includeDriverIds;
    
    /**
     * 派单超时时间(分钟)
     */
    @Min(value = 1, message = "派单超时时间不能小于1分钟")
    @Max(value = 60, message = "派单超时时间不能超过60分钟")
    @Schema(description = "派单超时时间(分钟)", example = "15")
    private Integer timeoutMinutes = 15;
    
    /**
     * 是否允许重复派单
     */
    @Schema(description = "是否允许重复派单", example = "true")
    private Boolean allowRedispatch = true;
    
    /**
     * 最大重派次数
     */
    @Min(value = 0, message = "最大重派次数不能为负数")
    @Max(value = 5, message = "最大重派次数不能超过5次")
    @Schema(description = "最大重派次数", example = "3")
    private Integer maxRedispatchCount = 3;
}